﻿import { Injectable } from '@nestjs/common';
import { createDecipheriv, createSign } from 'crypto';
import { join } from 'path';
import * as fs from 'fs';
import axios, { AxiosResponse } from 'axios';

@Injectable()
export class UtilsService {

    async paySign(timeStamp: string, nonceStr: string, prepay_id: string): Promise<string> {//小程序支付签名
        let paySignStr = `wxdc5881a7a5462f77\n${timeStamp}\n${nonceStr}\nprepay_id=${prepay_id}\n`;//构造签名串 待签名
        const key = fs.readFileSync(join(__dirname, '../../src/pay', 'apiclient_key.pem')).toString();
        const signature = createSign('RSA-SHA256').update(paySignStr, 'utf-8').sign(key, 'base64');
        return signature;
    }

    async getWechatSign(method: string, url: string, requestBody?: any) {//请求微信api
        const random = this.randomString();
        const date = (new Date().valueOf() / 1000).toFixed();
        let str: string;
        if (requestBody) {
            str = `${method}\n${url}\n${date}\n${random}\n${JSON.stringify(requestBody)}\n`;
        } else {
            str = `${method}\n${url}\n${date}\n${random}\n\n`;
        }
        const key = fs.readFileSync(join(__dirname, '../../src/pay', 'apiclient_key.pem')).toString();
        const signature = createSign('RSA-SHA256').update(str, 'utf-8').sign(key, 'base64');
        axios.defaults.baseURL = 'https://api.mch.weixin.qq.com';
        let result: AxiosResponse;
        axios.defaults.headers.common['Authorization'] = `WECHATPAY2-SHA256-RSA2048 mchid="1628971413",nonce_str="${random}",signature="${signature}",timestamp="${date}",serial_no="4E524E8AC8D85AE33014905C66D7836820699ACB"`;
        if (method === 'GET') {
            result = await axios.get(url);
        } else {
            result = await axios.post(url, requestBody);
        }




        return result.data;
    }

    randomString(len = 32) {

        let $chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678'
        let maxPos = $chars.length
        let str = ''
        for (let i = 0; i < len; i++) {
            str += $chars.charAt(Math.floor(Math.random() * maxPos))
        }
        return str
    }

    /**
     * 解密
     *
     * @param {string} cipherText 文本
     * @param {string} key 平台密钥
     * @param {string} iv 偏移量（nonce）
     * @param {string} add associated_data
     * @returns { id: '4200000421201910275143005680',appid: 'wx459f9b30b8d5b725',mchid: '105242849',out_trade_no: '1572159737154',payer: { openid: 'oDBryjphoxK-jG0UWcqEu4dCavZI' },amount:{ total: 10,currency: 'HKD',payer_total: 9,payer_currency: 'CNY',exchange_rate: { type: 'SETTLEMENT_RATE', rate: 100000000 } },trade_type: 'JSAPI',trade_state: 'SUCCESS',trade_state_desc: '支付成功',bank_type: 'CFT',success_time: '2019-10-27T15:02:26+08:00' }
     */
    getDecrypt(cipherText: any, key: string, iv: string, add: string): any {
        cipherText = Buffer.from(cipherText, 'base64');
        const authTag = cipherText.slice(cipherText.length - 16);
        const data = cipherText.slice(0, cipherText.length - 16);
        const decipher = createDecipheriv('aes-256-gcm', key, iv);
        decipher.setAuthTag(authTag);
        decipher.setAAD(Buffer.from(add));
        const decoded = decipher.update(data, null, 'utf8');
        decipher.final();
        console.log('=================解密后证书===================');
        console.log(decoded);
        console.log('====================================');
        return decoded;
    }
}
